package com.ctshk.rpc.system.service.impl;


import com.alibaba.fastjson.JSON;
import com.aliyuncs.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SysAreaLevel;
import com.ctshk.common.enums.bus.BusConst;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.HttpUtils;
import com.ctshk.common.utils.individual.scenic.PlaceUrlDetailDto;
import com.ctshk.common.utils.individual.scenic.ScenicInfoDetailDto;
import com.ctshk.rpc.system.dto.AreaTreeListDTO;
import com.ctshk.rpc.system.dto.ScenicAddressDTO;
import com.ctshk.rpc.system.entity.Scenic;
import com.ctshk.rpc.system.entity.SysArea;
import com.ctshk.rpc.system.mapper.ScenicMapper;
import com.ctshk.rpc.system.mapper.SysAreaMapper;
import com.ctshk.rpc.system.req.PhotoReq;
import com.ctshk.rpc.system.req.ScenicAddReq;
import com.ctshk.rpc.system.service.IScenicGetService;
import com.ctshk.rpc.system.service.ISysAreaService;
import com.github.houbb.opencc4j.util.ZhConverterUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.io.FileUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

/**
 * 一只爬虫用于爬取数据景点资源
 */
@DubboService
public class ScenicGetServiceImpl extends ServiceImpl<ScenicMapper, Scenic> implements IScenicGetService {

    private static String REDIS_COUNT_KEY = "REDIS_COUNT_KEY";
    private static String REDIS_CITY_KEY = "REDIS_CITY_KEY";
    private static String REDIS_NAME_KEY = "REDIS_NAME_KEY";
    private static String REDIS_SYN_AREA_ADDRESS_KEY = "REDIS_SYN_AREA_ADDRESS_KEY";
    private static String URL = "http://travel.qunar.com/place/?from=header";
    //    private static String url = "http://travel.qunar.com/p-cs299914-beijing-jingdian";
//    private static String url1 = "http://travel.qunar.com/p-oi711995-tiananmenguangchang";
    //填写admin账号为系统自动添加人
    private TokenUser tu = new TokenUser();
    //当前已经拉去的景点条数
    private static int COUNT = 0;
    //当前拉取的城市
    private static String CATIY = "";
    //百度地图接口地址
    private String url = "http://api.map.baidu.com/place/v2/search";
    private String ak = "cGksgHAP1phHdWnK0ZPIWFhlVK72lIGb";

    List<PlaceUrlDetailDto> placeList = new LinkedList<PlaceUrlDetailDto>();

    @Autowired
    private SceneServiceImpl sceneService;
    @Autowired
    private ScenicMapper scenicMapper;
    @Autowired
    private SysAreaMapper sysAreaMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private FileOSSServiceImpl fileOSSService;

    @DubboReference
    private ISysAreaService areaService;

    {
        tu.setId(BusConst.API_IMPORT_USER_ID);
    }

    @Override
    public com.alibaba.fastjson.JSONObject getProvinces(String name, String location) {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("output", "json");
        paramMap.put("ak", ak);
        paramMap.put("query", name);
        paramMap.put("location", location);
        String result = HttpUtils.httpget(url, paramMap);
        return JSON.parseObject(result);
    }

    @Override
    public Result syncCity() {
        //REDIS_SYN_AREA_ADDRESS_KEY
        ValueOperations ops = redisTemplate.opsForValue();
        int initSize = 1;//初始化起始页
        int pageNowSize = 0;//缓存记录行数
        if (redisTemplate.hasKey(REDIS_SYN_AREA_ADDRESS_KEY)) {
            pageNowSize = (int) ops.get(REDIS_SYN_AREA_ADDRESS_KEY);
        }
        System.out.println("=========================上次条数：" + pageNowSize);
        int sum = 0;//余数
        int size = 100;//页大小
        if (pageNowSize > 0) {
            initSize = pageNowSize / size;
            sum = pageNowSize % size;
        }
        //最大页数
        Integer count = scenicMapper.selectCount(Wrappers.<Scenic>lambdaQuery().eq(Scenic::getIsDeleted, IsDeletedCode.NO.getCode())) / size;
        for (int i = initSize; i <= count; i++) {
            //一页一页的翻
            Page<Scenic> iPage = new Page<>(i, size);
            Page<Scenic> scenicPage = scenicMapper.selectPage(iPage, Wrappers.<Scenic>lambdaQuery().eq(Scenic::getIsDeleted, IsDeletedCode.NO.getCode()));
            List<Scenic> records = scenicPage.getRecords();//第n页的数据
            if (records != null && records.size() > 0) {
                //跳过余数
                for (int j = sum; j < records.size(); j++) {
                    if (sum > 0) {
                        sum = 0;//余数只使用一次，大于0候重置
                    }
                    Scenic e = records.get(j);
                    //跳过
                    if (e.getAreaId() != null && !e.getAreaId().toString().substring(0, 1).equals("6")) {
                        continue;
                    }
                    SysArea city = getCity(e.getLat(), e.getLon());
                    if (city != null) {
                        e.setAreaType(city.getLevel());
                        e.setAreaId(city.getId());
                        /**
                         * 这里的常量值需要和它保持一致
                         * @see SysAreaLevel
                         */
                        switch (city.getLevel()) {
                            case 1:
                                e.setAreaName(city.getCountryTraditional());
                                break;
                            case 2:
                                e.setAreaName(city.getProvinceTraditional());
                                break;
                            case 3:
                                e.setAreaName(city.getCityTraditional());
                                break;
                        }
                    }
                    scenicMapper.updateById(e);
                    //当前记录数
                    ops.set(REDIS_SYN_AREA_ADDRESS_KEY, ++pageNowSize);
                }
            }
            System.out.println("共计" + count + "页，每页" + size + "条数据，当前第" + i + "页！");
        }
        return Result.success();
    }

    @Override
    public Result syncCity2() {
        List<Scenic> records = scenicMapper.selectList(Wrappers.<Scenic>lambdaQuery()
                .likeRight(Scenic::getAreaId,"1")
                .eq(Scenic::getIsDeleted, IsDeletedCode.NO.getCode())
        );
//        List<Scenic> records = scenicMapper.selectList(Wrappers.<Scenic>lambdaQuery()
//                .isNull(Scenic::getAreaId)
//                .eq(Scenic::getIsDeleted, IsDeletedCode.NO.getCode())
//        );
//        records.addAll(records2);
        if (records != null && records.size() > 0) {
            //跳过余数
            for (int j = 0; j < records.size(); j++) {
                Scenic e = records.get(j);
                //跳过
                if (e.getAreaId() != null && !e.getAreaId().toString().substring(0, 1).equals("6")) {
                    continue;
                }
                SysArea city = getCity(e.getLat(), e.getLon());
                if (city != null) {
                    e.setAreaType(city.getLevel());
                    e.setAreaId(city.getId());
                    /**
                     * 这里的常量值需要和它保持一致
                     * @see SysAreaLevel
                     */
                    switch (city.getLevel()) {
                        case 1:
                            e.setAreaName(city.getCountryTraditional());
                            break;
                        case 2:
                            e.setAreaName(city.getProvinceTraditional());
                            break;
                        case 3:
                            e.setAreaName(city.getCityTraditional());
                            break;
                    }
                }
                scenicMapper.updateById(e);
            }
//            updateBatchById(records);
        }
        return Result.success();
    }

    private SysArea getCity(BigDecimal lat, BigDecimal lon) {
        String url = "http://api.map.baidu.com/batch";
        Map<String, String> paramMap = new HashMap<>();
        JSONObject body = new JSONObject();
        JSONArray ja = new JSONArray();
        JSONObject reqs = new JSONObject();
        reqs.put("method", "get");
        reqs.put("url", "/reverse_geocoding/v3/?location=" + lat + "," + lon + "&output=json&entensions_poi=0&ak=" + ak);
        ja.add(reqs);
        body.put("reqs", ja);
        try {
            String result = HttpUtils.sendHttpSslPost(url, body.toString());
            com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(result).getJSONArray("batch_result").getJSONObject(0).getJSONObject("result").getJSONObject("addressComponent");
            String city = jsonObject.getString("city");//市区3
            String province = jsonObject.getString("province");//省份2
            String country = jsonObject.getString("country");//国家1
            QueryWrapper<SysArea> qw = new QueryWrapper<>();
            qw.lambda().eq(SysArea::getIsDeleted, IsDeletedCode.NO.getCode());
            //取低级优先
            if (!StringUtils.isEmpty(city)) {
                qw.lambda().eq(SysArea::getLevel, SysAreaLevel.THREE.getCode())
                        .and(e -> e
                                .or().like(SysArea::getCityTraditional, city)
                                .or().like(SysArea::getCitySimple, city)
                        );
            } else if (!StringUtils.isEmpty(province)) {
                qw.lambda().eq(SysArea::getLevel, SysAreaLevel.TWO.getCode())
                        .and(e -> e
                                .or().like(SysArea::getProvinceSimple, province)
                                .or().like(SysArea::getProvinceTraditional, province)
                        );
            } else {
                qw.lambda().eq(SysArea::getLevel, SysAreaLevel.ONE.getCode())
                        .and(e -> e
                                .or().like(SysArea::getCountrySimple, country)
                                .or().like(SysArea::getCountryTraditional, country)
                        );
            }
            List<SysArea> sysAreas = sysAreaMapper.selectList(qw);
            if (sysAreas != null && sysAreas.size() > 0) {
                return sysAreas.get(0);
            } else {
                //地区补偿
                if (!StringUtils.isEmpty(province)) {
                    qw.clear();
                    qw.lambda().eq(SysArea::getIsDeleted, IsDeletedCode.NO.getCode());
                    qw.lambda().eq(SysArea::getLevel, SysAreaLevel.TWO.getCode())
                            .and(e -> e
                                    .or().like(SysArea::getProvinceSimple, province)
                                    .or().like(SysArea::getProvinceTraditional, province)
                            );
                    sysAreas = sysAreaMapper.selectList(qw);
                    if (sysAreas != null && sysAreas.size() > 0) {
                        return sysAreas.get(0);
                    } else {
                        qw.clear();
                        qw.lambda().eq(SysArea::getIsDeleted, IsDeletedCode.NO.getCode());
                        qw.lambda().eq(SysArea::getLevel, SysAreaLevel.ONE.getCode())
                                .and(e -> e
                                        .or().like(SysArea::getCountrySimple, country)
                                        .or().like(SysArea::getCountryTraditional, country)
                                );
                        sysAreas = sysAreaMapper.selectList(qw);
                        if (sysAreas != null && sysAreas.size() > 0) {
                            return sysAreas.get(0);
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("查询城市出现错误：" + e.getMessage());
        }
        return null;
    }

    @Override
    public void scenicTask(boolean flage, String catiyName, int count) {
        try {
            fileOSSService.createBucketByName(FileOSSServiceImpl.SCENIC_IMG_SPACE);
            boolean bool = redisTemplate.hasKey(REDIS_COUNT_KEY);
            if (bool) {
                ValueOperations ops = redisTemplate.opsForValue();
                COUNT = (int) ops.get(REDIS_COUNT_KEY);
                CATIY = (String) ops.get(REDIS_NAME_KEY);
            }
            if (flage) {
                COUNT = count > 0 ? count : 0;
                CATIY = StringUtils.isEmpty(catiyName) ? "" : catiyName;
            }
            getDestination(URL);
        } catch (IOException e) {
            System.out.println("爬取景点出现错误：" + e.getMessage());
        }
    }

    /**
     * 获取目的地，链接
     *
     * @param URL
     * @throws IOException
     */
    private void getDestination(String URL) throws IOException {
        //通过延迟2000毫秒然后再去请求可解决js异步加载获取不到数据的问题
        Document doc = Jsoup.connect(URL).timeout(60000).get();
        Elements elements = doc.getElementsByClass("contbox current");
        System.out.println("抓取地址---------------------Start");
        boolean bool = false;
        ValueOperations ops = redisTemplate.opsForValue();
        String citys = (String) ops.get(REDIS_CITY_KEY);
        if (StringUtils.isEmpty(citys)) {
            for (int i = 0; i < elements.size(); ++i) {
                Element tr = elements.get(i);
                Elements td = tr.getElementsByClass("listbox");//获取区域
                for (Element q : td) {//获取第一个区域
                    //获取名称
                    Elements qy = q.getElementsByClass("hd");//获取区域
                    //获取明细
                    Elements sub_list = q.getElementsByClass("item");//获取目的地
                    if (sub_list != null) {
                        for (Element sub : sub_list) {
                            if ("中国".equals(sub.text())) {
                                bool = true;
                                continue;
                            }
                            Element link = sub.select("a").first();
                            String url = link.attr("href");
                            if (!bool) {
                                PlaceUrlDetailDto place = new PlaceUrlDetailDto();
                                place.setName(sub.text());
                                place.setSuperior(qy.text());
                                place.setFlag("" + 0);
                                place.setUrl(url);
                                placeList.add(place);
                            } else {
                                Document d2 = Jsoup.connect(url).timeout(60000).get();
                                Elements e2 = d2.getElementsByClass("line clrfix");
                                try {
                                    Element element = e2.get(1);//拿到中间热门城市的dl元素
                                    Elements tss = element.getElementsByClass("tag show");
                                    if (tss != null) {
                                        for (Element e : tss) {
                                            Element a = e.select("a").first();
                                            String h = a.attr("href");
                                            PlaceUrlDetailDto place = new PlaceUrlDetailDto();
                                            String cName = e.text();
                                            int l = cName.indexOf("旅");
                                            if (l != -1) {
                                                place.setName(cName.substring(0, l));
                                            } else {
                                                place.setName(cName);
                                            }
                                            place.setSuperior(qy.text());
                                            place.setFlag("" + 1);
                                            place.setUrl(h);
                                            placeList.add(place);
                                        }
                                    }
                                } catch (IndexOutOfBoundsException e) {
                                    //拿不到就是没有城市
                                }
                            }
                        }
                    }
                }
            }
            ops.set(REDIS_CITY_KEY, JSON.toJSONString(placeList));
        } else {
            com.alibaba.fastjson.JSONArray jsons = JSON.parseArray(citys);
            placeList = jsons.toJavaList(PlaceUrlDetailDto.class);
        }
        System.out.println("抓取地址---------------------End\t共计：" + placeList.size() + "个地区！");
        int sum = 0;//定义一次减扣量
        if (COUNT > 0) {
            sum = COUNT;
        }
        boolean flage = false;
        System.out.println("\n\n\n正在获取景点链接---------------------Start");
        //遍历目的地链接 获取景点链接
        for (PlaceUrlDetailDto placeList1 : placeList) {
            if (!StringUtils.isEmpty(CATIY)) {
                //如果拿到了城市就判断是否和当前拉去的城市相等（不相等就跳过）
                if (!CATIY.equals(placeList1.getName()) && flage == false) {
                    continue;
                }
            }
            flage = true;//打开标记
            //如果匹配上了就刷新当前城市名称
            CATIY = placeList1.getName();
            ops.set(REDIS_NAME_KEY, CATIY);
            String url1 = placeList1.getUrl() + "-jingdian";
            String s1 = ZhConverterUtil.toTraditional(placeList1.getName());//当前城市的繁体
            List<AreaTreeListDTO> areaTreeListDTOS = areaService.queryAreaLikeName(s1);
            Long areaId = null;
            if (CollectionUtils.isNotEmpty(areaTreeListDTOS)) {
                areaId = areaTreeListDTOS.get(0).getId();
            }
            List<ScenicAddressDTO> infoUrl = getInfoUrl(url1);
            if (infoUrl != null && COUNT >= infoUrl.size()) {
                COUNT = 0;//下一次重置数量
            }
            if (sum > 0) {
                if (sum >= infoUrl.size()) {
                    sum -= infoUrl.size();
                    continue;
                } else {
                    infoUrl = infoUrl.subList(sum - 1, infoUrl.size());
                    sum = 0;
                }
            }
            for (ScenicAddressDTO s : infoUrl) {
                try {
                    getInfoDetail(s, placeList1.getName(), areaId);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("获取景点链接---------------------End");
    }

    /**
     * 获取景点详情url
     *
     * @param url1
     * @throws IOException
     */
    private List<ScenicAddressDTO> getInfoUrl(String url1) throws IOException {
        Document doc1 = Jsoup.connect(url1).timeout(60000).get();
        List<ScenicAddressDTO> sas = new LinkedList<>();
        Elements totalPages = doc1.getElementsByClass("page");
        int totalPage = 1;
        if (totalPages.size() > 1) {
            totalPage = Integer.valueOf(totalPages.get(totalPages.size() - 2).text());
        }
        for (int t = 0; t < totalPage; ++t) {//遍历分页
            int param = t + 1;
            String url2 = url1 + "-1-" + param;
            Document doc = Jsoup.connect(url2).timeout(60000).get();
            Elements elements = doc.getElementsByClass("list_item clrfix");
            for (int i = 0; i < elements.size(); ++i) {
                //获取景点信息
                Element tr = elements.get(i);
                Elements item = tr.getElementsByClass("item");
                for (int j = 0; j < item.size(); ++j) {
                    ScenicAddressDTO sadto = new ScenicAddressDTO();
                    Element items = item.get(j);
                    sadto.setLag(items.attr("data-lng"));//经度
                    sadto.setLat(items.attr("data-lat"));//纬度
                    //获取url
                    Element titlink = items.getElementsByClass("titlink").first();
                    sadto.setUrl(titlink.attr("href"));
                    sas.add(sadto);
                }
            }
        }
        System.out.println("从地址：" + url1 + "\t抓取到" + sas.size() + "个景点链接！");
        return sas;
    }

    /**
     * 获取景点信息
     *
     * @param sadto
     * @throws IOException
     */
    private void getInfoDetail(ScenicAddressDTO sadto, String pName, Long areaId) throws Exception {
        //通过延迟然后再去请求可解决js异步加载获取不到数据的问题
        Document doc = Jsoup.connect(sadto.getUrl()).timeout(60000).get();
        Elements elements = doc.getElementsByClass("b_title clrfix");
        ScenicInfoDetailDto scenic = new ScenicInfoDetailDto();
        while (elements == null || elements.size() <= 0) {
            verificationCode();
            doc = Jsoup.connect(sadto.getUrl()).timeout(60000).get();
            elements = doc.getElementsByClass("b_title clrfix");
        }
        getScenicInfo(elements, scenic, doc, pName, sadto, areaId);
    }

    /**
     * 获取景点信息
     *
     * @param elements
     * @param scenic
     * @param doc
     * @param pName
     */
    private void getScenicInfo(Elements elements, ScenicInfoDetailDto scenic, Document doc, String pName, ScenicAddressDTO sadto, Long areaId) throws Exception {
        for (int i = 0; i < elements.size(); ++i) {
            String cn = null;
            String en = null;
            Element tr = elements.get(i);
            Elements item = tr.getElementsByClass("tit");
            for (int j = 0; j < item.size(); ++j) {
                Element items = item.get(j);
                cn = items.text(); //中文名
            }
            Elements entit = tr.getElementsByClass("entit");
            for (int j = 0; j < entit.size(); ++j) {
                Element entits = entit.get(j);
                en = entits.text();//英文名
                scenic.setEName(en);
            }
            String sb = cn;
            String str = sb.substring(0, sb.indexOf(en));
            if (str == null || "".equals(str)) {
                scenic.setName(cn);//中文名
            } else {
                scenic.setName(str);//截取后的中文名
            }
            scenic.setPName(pName);
            //评分
//            Elements scores = doc.getElementsByClass("score");
//            String score = scores.get(0).text();
//            scenic.setScore(score);
            //排名
//            Elements ranking = doc.getElementsByClass("ranking");
//            Elements sums = ranking.get(0).getElementsByClass("sum");
//            String sum = sums.get(0).text();
//            scenic.setRank(sum);
            //景点数量
//            Elements counts = ranking.get(0).getElementsByClass("link");
//            String count = counts.get(0).text();
//            scenic.setCount(count);
            //游玩时间
            Elements scorebox = doc.getElementsByClass("m_scorebox");
            if (scorebox != null && scorebox.size() > 0) {
                Elements times = scorebox.get(0).getElementsByClass("time");
                if (times != null && times.size() > 0) {
                    String time = times.get(0).text();
                    scenic.setTourismSeason(time);
                }
            }
            //概述
            Elements detail = doc.getElementsByClass("b_detail_section b_detail_summary");
            if (detail != null && detail.size() > 0) {
                Elements content_box = detail.get(0).getElementsByClass("e_db_content_box");
                if (content_box != null && content_box.size() > 0) {
                    String content = content_box.get(0).text();
                    scenic.setDes(content);
                }
            }
            //地址td_l
            Elements td_l = doc.getElementsByClass("td_l");
            if (td_l != null && td_l.size() > 0) {
                Elements s = td_l.get(0).select("span");
                if (s.size() > 0) {
                    String address = s.get(0).text();
                    scenic.setAddress(address);
                }
                //电话
                if (s.size() > 1) {
                    String phone = s.get(1).text();
                    scenic.setPhone(phone);
                }
            }
            //开放时间td_r
            Elements td_r = doc.getElementsByClass("td_r");
            if (td_l != null && td_l.size() > 0) {
                Elements openTimes = td_r.get(0).select("span");
                if (openTimes != null && openTimes.size() > 0) {
                    String openTime = openTimes.get(0).text();
                    scenic.setTime(openTime);
                }
            }
            //旅游时节
            Elements travelseason = doc.getElementsByClass("b_detail_section b_detail_travelseason");
            if (travelseason != null && travelseason.size() > 0) {
                //交通指南（地铁公交）e_db_content_box e_db_content_dont_indent
                Elements traffic = doc.getElementsByClass("b_detail_section b_detail_traffic");
                if (traffic != null && traffic.size() > 0) {
                    Elements indents = traffic.get(0).getElementsByClass("e_db_content_box e_db_content_dont_indent");
                    if (indents != null && indents.size() > 0) {
                        String indent = indents.get(0).text();
                        scenic.setBus(indent);
                    }
                }
            }
            //图片链接e_slider_con_box
            Document docpic = Jsoup.connect(sadto.getUrl()).timeout(60000).get();
            Elements pois = docpic.getElementsByClass("btnbox e_strategy");
            if (pois != null && pois.size() > 0) {//判断是否有10张图片，是否输验证码
                Element po = pois.get(0).select("a").first();
                String poii = po.attr("data-id");
                //发送更多图片请求
                String morePicUrl = "http://travel.qunar.com/place/api/poi/image?offset=0&limit=16&poiId=" + poii;//请求路径
                String picUrls = sendGet(morePicUrl);//从链接中取10张大图链接
                if (!StringUtils.isEmpty(picUrls)) {
                    scenic.setPicUrl(picUrls);
                }
            } else {//判断是否要验证码
                while (elements == null || elements.size() <= 0) {
                    verificationCode();
                    doc = Jsoup.connect(sadto.getUrl()).timeout(60000).get();
                    elements = doc.getElementsByClass("b_title clrfix");
                }
            }
            ScenicAddReq addReq = new ScenicAddReq();
            addReq.setName(ZhConverterUtil.toTraditional(scenic.getName()));
            addReq.setAreaId(areaId);
            addReq.setAreaName(ZhConverterUtil.toTraditional(scenic.getPName()));
            addReq.setIntroduce(ZhConverterUtil.toTraditional(scenic.getDes()));
            addReq.setScenicLocation(ZhConverterUtil.toTraditional(scenic.getAddress()));
            addReq.setScenicLevel(scenic.getRank());
            if (sadto.getLat() != null) {
                addReq.setLat(new BigDecimal(sadto.getLat()));
            }
            if (sadto.getLag() != null) {
                addReq.setLon(new BigDecimal(sadto.getLag()));
            }
            List<PhotoReq> list = new ArrayList<>();
            if (!"".equals(scenic.getPicUrl()) && scenic.getPicUrl() != null) {
                String[] arr = scenic.getPicUrl().split(",");
                for (String address : arr) {
                    String uuid = UUID.randomUUID().toString();
                    // 获取图片的扩展名
                    String extensionName = address.substring(address.lastIndexOf(".") + 1);
                    // 新的图片文件名 = 编号 +"."图片扩展名
                    String newFileName = uuid + "." + extensionName;
                    InputStream is = download(address, extensionName);
                    String s = fileOSSService.uploadFile2OSS(FileOSSServiceImpl.SCENIC_IMG_SPACE, is, newFileName);
                    PhotoReq pr = new PhotoReq();
                    pr.setId(uuid);
                    pr.setFiles(s);
                    pr.setTitle(newFileName);
                    list.add(pr);
                }
                addReq.setCoverPhoto(arr[0]);
            }
            addReq.setPhotoJson(list);
            addReq.setAdmissionNotes(ZhConverterUtil.toTraditional(scenic.getTime()));
            sceneService.add(addReq, tu);
            System.out.println("当前共计拉取景点条数：" + ++COUNT + "\n");
            ValueOperations ops = redisTemplate.opsForValue();
            ops.set(REDIS_COUNT_KEY, COUNT);
        }
    }

    private String sendGet(String url) {
        String picUrl = null;
        try {
            String datas = HttpUtils.sendHttpSslPost(url, "");
            JSONObject json = JSONObject.fromObject(datas);
            JSONArray dataDetail = (JSONArray) json.get("data");
            for (int i = 0; i < 10; ++i) {
                if (dataDetail != null && dataDetail.size() > 10) {
                    if (dataDetail.get(i) != null) {
                        Object o = dataDetail.get(i);
                        Map entry = (Map) o;
                        Object d = entry.get("bigImageURL");
                        if (i > 0) {
                            picUrl = picUrl + "," + d.toString();
                        } else if (i == 0) {
                            picUrl = d.toString();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return picUrl;
    }

    /**
     * 下载图片
     *
     * @param urlString
     * @throws Exception
     */
    public InputStream download(String urlString, String extensionName) throws Exception {
        java.net.URL url = new URL(urlString);
        URLConnection con = url.openConnection();
        con.setConnectTimeout(50 * 1000);
        InputStream is = con.getInputStream();
        //临时文件
        String name = Thread.currentThread().getName();
        File flie = new File("./" + name + "a." + extensionName);
        if (flie.exists()) {
            flie.delete();
        }
        try {
            flie.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        FileOutputStream fos = new FileOutputStream(flie);
        byte[] data = new byte[1024 * 1024];
        int len = 0;
        while ((len = is.read(data)) != -1) {
            fos.write(data, 0, len);
        }
        fos.flush();
        fos.close();
        FileInputStream fis = new FileInputStream(flie);
        return fis;
    }

    public static String convertFileToBase64(File file) {
        byte[] data = null;
        // 读取图片字节数组
        try {
            InputStream in = new FileInputStream(file);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组进行Base64编码，得到Base64编码的字符串
        Base64.Encoder encoder1 = Base64.getEncoder();
        String base64Str = new String(encoder1.encode(data));
        return base64Str;
    }

    /**
     * 识别验证码
     *
     * @param imageBase64
     * @return
     * @throws IOException
     */
    public static String hack(String imageBase64) throws IOException {
        //用户名
        String username = "mikesam";
        //密码
        String password = "hbca257d";
        //备注字段: 可以不写
        String remark = "输出计算结果";
        Map<String, String> data = new HashMap<>();
        data.put("username", username);
        data.put("password", password);
        data.put("typeid", "1003");
        data.put("remark", remark);
        data.put("image", imageBase64);
        String resultString = Jsoup.connect("http://api.ttshitu.com/predict")
                .requestBody(JSON.toJSONString(data))
                .header("Content-Type", "application/json")
                .ignoreContentType(true).timeout(120000).post().text();
        com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(resultString);
        if (jsonObject.getBoolean("success")) {
            String result = jsonObject.getJSONObject("data").getString("result");
            System.out.println("识别成功结果为:" + result);
            return result;
        } else {
            System.out.println("识别失败原因为:" + jsonObject.getString("message"));
        }
        return null;
    }

    /**
     * 解析验证码并验证
     *
     * @throws Exception
     */
    public void verificationCode() throws Exception {
        String url = "http://travel.qunar.com/space/captcha?from=http%3A%2F%2Ftravel.qunar.com%2Fplace%2Fpoi%2Fgugong-710603-";
        System.setProperty("webdriver.chrome.driver", "/mnt/usr/local/driver/chromedriver");
        ChromeOptions option = new ChromeOptions();
        option.addArguments("--no-sandbox");
        option.addArguments("--disable-dev-shm-usage");
        option.addArguments("--headless");
        option.setHeadless(true);
        WebDriver driver = new ChromeDriver(option);
        driver.get(url);
        String name = Thread.currentThread().getName();//抓取线程名称生成图片
        File file = new File("./" + name + "code.png");
        if (file.exists()) {
            file.delete();
        }
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        driver.manage().window().maximize();
        //执行屏幕截图操作
        File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
        //通过FileUtils中的copyFile()方法保存getScreenshotAs()返回的文件;"屏幕截图"即时保存截图的文件夹
        try {
            FileUtils.copyFile(srcFile, file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        cut(file, file, 120, 90, 110, 36);
        String s = convertFileToBase64(file);
        String code = hack(s);
        System.out.println("====================解析验证码结果：" + code);
        driver.findElement(new By.ById("code")).sendKeys(code);
        Thread.sleep(500);
        WebElement btn_submit = driver.findElement(By.className("btn_submit"));
        btn_submit.click();
        String title1 = driver.getTitle();
        if (!"旅行攻略验证码".equals(title1)) {
            System.out.println("===========验证成功");
        } else {
            System.out.println("===========验证失败");
        }
        driver.quit();
        if (file.exists()) {
            file.delete();
        }
    }

    /**
     * 截取图片
     *
     * @param srcpath 截取前的图片
     * @param subpath 截取后的图片
     * @param x       x轴偏移
     * @param y       y轴偏移
     * @param width   截取的宽度
     * @param height  截取的高度
     * @throws IOException
     */
    public static void cut(File srcpath, File subpath, int x, int y, int width, int height) throws IOException {
        FileInputStream is = null;
        ImageInputStream iis = null;
        try {
            //读取图片文件
            is = new FileInputStream(srcpath);
            String suffix = "png";
            Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(suffix);
            ImageReader reader = it.next();
            //获取图片流
            iis = ImageIO.createImageInputStream(is);
            reader.setInput(iis, true);
            ImageReadParam param = reader.getDefaultReadParam();
            java.awt.Rectangle rect = new java.awt.Rectangle(x, y, width, height);
            param.setSourceRegion(rect);
            BufferedImage bi = reader.read(0, param);
            //保存新图片
            ImageIO.write(bi, "png", subpath);
        } finally {
            if (is != null)
                is.close();
            if (iis != null)
                iis.close();
        }
    }
}
